package club.jdiy.core.job.entity;

import club.jdiy.core.base.domain.JpaEntity;
import club.jdiy.core.job.exec.CronUtils;
import club.jdiy.utils.StringUtils;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
import java.util.Date;

/**
 * JDiy定时任务调度
 *
 * @author ziquee(子秋) QQ号:39886616 主页: http://www.jdiy.club
 * @version 20210622
 */
@NoArgsConstructor
@Data
@Entity
@Table(name = "jdiy_job")
public class JDiyJob implements JpaEntity<Long> {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @NotEmpty(message = "任务名称不能为空")
    @Pattern(regexp = "[a-zA-Z][a-zA-Z0-9]*", message = "任务名称只能由英文字母或数字的组合，且不能以数字开头.")
    @Column(columnDefinition = "varchar(64) not null comment '任务名称（a-z0-9）'")
    private String jobName;
    @NotEmpty
    @NotEmpty(message = "任务分组不能为空")
    @Pattern(regexp = "[a-zA-Z][a-zA-Z0-9]*", message = "任务分组只能由英文字母或数字的组合，且不能以数字开头.")
    @Column(columnDefinition = "varchar(64) not null comment '任务分组'")
    private String jobGroup;
    @NotEmpty(message = "任务cron表达式不能为空")
    @Column(columnDefinition = "varchar(128) not null comment '任务cron表达式'")
    private String jobCron;
    @NotEmpty(message = "任务执行代码不能为空")
    @Column(columnDefinition = "text")
    private String jobExecute;
    @Column(columnDefinition = "bit default 0 not null comment '记录日志(0:否 1:是)'")
    private Boolean jobLog;
    @Column(columnDefinition = "bit default 0 not null comment '是否并发执行（0禁止 1允许）'")
    private Boolean jobConcurrent;
    @Column(columnDefinition = "bit default 0 not null comment '任务状态（0正常 1暂停）'")
    private Boolean jobPause;
    @Column(columnDefinition = "int default 0 not null comment 'cron计划策略 0=默认,1=立即触发执行,2=触发一次执行,3=不触发立即执行'")
    private Integer jobMisfire;
    @Column(columnDefinition = "text")
    private String jobRemark;

    public JDiyJob(Long id) {
        this.id = id;
    }

    public JDiyJob(String jobName, String jobGroup) {
        this.jobName = jobName;
        this.jobGroup = jobGroup;
    }

    @PreUpdate
    @PrePersist
    private void init() {
        if (jobPause == null) jobPause = false;
        if (jobConcurrent == null) jobConcurrent = false;
        if (jobLog == null) jobLog = false;
        if (jobMisfire == null) jobMisfire = 2;
    }

    public Date getNextValidTime() {
        if (StringUtils.hasText(jobCron)) {
            return CronUtils.getNextExecution(jobCron);
        }
        return null;
    }
}